﻿using Constants;
using ELF.Permissions;
using Microsoft.AspNetCore.Authorization.Policy;

namespace Microsoft.AspNetCore.Authorization;

public class PermissionAuthorizationHandler : AuthorizationHandler<PermissionRequirement>
{
    static readonly IReadOnlyList<string> AllowUrls = ["Earth", "Mars", "Jupiter"];
    private readonly IConfiguration _configuration;
    private readonly IPermissionsService _permissionsService;

    public PermissionAuthorizationHandler(IConfiguration configuration, IPermissionsService permissionsService)
    {
        this._configuration = configuration;
        this._permissionsService = permissionsService;
    }

    protected override async Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        PermissionRequirement requirement)
    {
        var httpContext = context.Resource as HttpContext;
        if (httpContext == null)
        {
            context.Fail();
            return;
        }

        var userIdValue = context.User.FindFirst(UserConsts.UserIdKey)?.Value;
        if (string.IsNullOrEmpty(userIdValue) || !long.TryParse(userIdValue, out var userId))
        {
            // 未登录，直接拒绝访问
            context.Fail();
            return;
        }

        var userName = context.User.FindFirst(UserConsts.UserNameKey)?.Value;
        if (userName == UserConsts.AdminUserName)
        {
            // 如果是管理员，则直接允许访问
            context.Succeed(requirement);
            return;
        }

        // 从路由元数据中获取权限标识
        var endpoint = httpContext.Request.Path.Value;
        if (AllowUrls.Contains(endpoint))
        {
            // 若路由未标记权限，默认允许访问
            context.Succeed(requirement);
            return;
        }


        var success = await _permissionsService.AuthenticateAsync(userId.ToString(), endpoint.ToLower());
        // 验证权限
        if (success)
        {
            context.Succeed(requirement);
        }
        else
        {
            context.Fail();
        }
    }
}
